
from flask import Flask, jsonify, g, request
from flask_cors import CORS

from db_utils.postgresql_connection import PostgreSQLConnection
from db_utils.repositories.tokens_table import TokensTable
from db_utils.repositories.user_roles_table import UserRolesTable
from db_utils.repositories.permission_aggregation_interface import PermissionAggregationInterface

from flask_blueprints.user_blueprint import user_blueprint
from flask_blueprints.permission_blueprint import permission_blueprint
from flask_blueprints.device_blueprint import device_blueprint
from flask_blueprints.srm_blueprint import srm_blueprint
from flask_blueprints.video_resources_blueprint import video_resources_blueprint
from flask_blueprints.device_notify_blueprint import device_notify_blueprint
from flask_blueprints.send_command_blueprint import send_command_blueprint
from flask_blueprints.wx_login_blueprint import wx_login_blueprint
from flask_blueprints.wx_device_blueprint import wx_device_blueprint
app = Flask(__name__)
CORS(app)
app.register_blueprint(user_blueprint)
app.register_blueprint(permission_blueprint)
app.register_blueprint(device_blueprint)
app.register_blueprint(srm_blueprint)
app.register_blueprint(video_resources_blueprint)
app.register_blueprint(device_notify_blueprint)
app.register_blueprint(send_command_blueprint)

app.register_blueprint(wx_login_blueprint, url_prefix='/wx')
app.register_blueprint(wx_device_blueprint, url_prefix='/wx')


# 忽略权限验证的路由

no_auth_required_routes = [
     '/',
     '/login',
     '/register_user',
     '/wx/wx_login',
     '/wx/wx_get_user_phone',
     '/wx/update_user_info',
     '/wx/bind_device',
     '/wx/unbind_device',
     '/wx/query_bind_devices',
     '/wx/delete_bind',
     '/wx/query_device_data'
 ]
 
@app.before_request
def before_request():

    if request.path not in no_auth_required_routes:
        # check if token is present in the request header

        token = request.headers.get('Authorization') # 如果微信不让你用Authorization，可以用token来代替

        if not token:

            token = request.headers.get('token')

        if not token:

            token = request.args.get('token') # 如果微信不让你用Header方式，可以用传参方式来代替

        if not token:
            return jsonify({
                "status": -1,
                "errorCode": 1,
                "errorMsg": "Token is missing in the request header",
                "resultBody": None
            })
        

        # verify token here

        if token == "root": # 这里设置一个超级管理员的token，用来测试接口是否正常

            g.user_id = 1 # 设置超级管理员的user_id
            g.role = "root" # 设置超级管理员的角色
                
        else:
            with PostgreSQLConnection() as (conn, cur):


                # 验证token是否有效

                token_table_methods = TokensTable(conn, cur)

                verify_token_result = token_table_methods.verify_token(token) 

                if not verify_token_result[0]: 

                    return jsonify({"status": -1, "errorCode": 2, "errorMsg": "Token is invalid", "resultBody": None})

                g.user_id = verify_token_result[1]
                
                # 验证用户是否有权限访问该接口
                is_permission_allowed = PermissionAggregationInterface(conn, cur, g.user_id, request.path).is_permission_allowed

                if not is_permission_allowed:
    
                    return jsonify({"status": -1, "errorCode": 3, "errorMsg": "User has no permission to access this interface", "resultBody": None})

            
        app.logger.debug(f'user_id: {g.user_id}')

    else:
        app.logger.debug(f'{request.path} 在 no_auth_required_routes 列表中，不需要验证token')
 
 
 # @app.after_request
 # def after_request(response):
 #     app.logger.debug('after_request')
 #     return response
 
 
 # @app.teardown_request
 # def teardown_request(exception):
 #     app.logger.debug('teardown_request')
 
 #     return exception

@app.route('/', methods=['GET'])
def index():
    return jsonify({
        "status": 1,
        "errorCode": None,
        "errorMsg": None,
        "resultBody": "Welcome to Baina IOT Integrated Platform"
    })


if __name__ == '__main__':

    app.run(debug=True, host='0.0.0.0', port=5000)